﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using Cubicle.Core.DataContracts;
using Cubicle.Core.Interfaces;

namespace Cubicle.Core.Repository
{
    public class RObject : IRObject
    {
        public IDictionary<string, object> Metadata { get; private set; }
        public virtual object Object { get; set; }
        public string Handle { get; set; }
        public string Key { get; set; }
        public IHandleParser Parser { get; set; }
        public IRepository Repo { get; private set; }

        public event EventHandler<RepoEventArgs> Remove = delegate { };
        public void OnRemove(object sender, RepoEventArgs args) { Remove(sender, args); }

        public event EventHandler<RepoEventArgs> Get = delegate { };
        public void OnGet(object sender, RepoEventArgs args) { Get(sender, args); }

        public event EventHandler<RepoEventArgs> Set = delegate { };
        public void OnSet(object sender, RepoEventArgs args) { Set(sender, args); }

        public RObject(IHandleParser parser, string key, object value, IRepository repo)
        {
            Key = key;
            Parser = parser;
            Handle = parser.KeyToHandle(key);
            Object = value;
            Repo = repo;
            Metadata = new Dictionary<string, object>();
        }

    }

    public static class DynamicItemProperties
    {

        public const string ProgressKey = "Progress";
        public static void Progress(this DynamicItem request, double value)
        {
            request[ProgressKey] = value;
            request.RaisePropertyChanged(null, new PropertyChangedEventArgs(ProgressKey));
        }

        public static double Progress(this DynamicItem request)
        {
            return request.Get<double>(ProgressKey, 0);
        }

        public const string TargetTypeKey = "TargetType";
        public static Type TargetType(this DynamicItem request, Type value = null)
        {
            if (value == null) return request.Get<Type>(TargetTypeKey, null);
            request[TargetTypeKey] = value;
            request.RaisePropertyChanged(null, new PropertyChangedEventArgs(TargetTypeKey));
            return value;
        }

    }

    public class DynamicItem : Dictionary<string, object>, INotifyPropertyChanged
    {
        public T Get<T>(string key, T failValue)
        {
            object tmp;
            TryGetValue(key, out tmp);
            return tmp == null
                ? failValue
                : (T)tmp;
        }

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public void RaisePropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            PropertyChanged(sender, args);
        }

    }


}